package com.finesys.backend.api.controller.user;

import com.finesys.backend.api.anno.LoggerPolicy;
import com.finesys.backend.api.config.RestApiConfig;
import com.finesys.backend.api.controller.base.BaseController;
import com.finesys.backend.api.model.vo.LoginInfoVo;
import com.finesys.backend.api.model.vo.UserInfoVo;
import com.finesys.backend.common.model.base.BusinessResult;
import com.finesys.backend.common.model.base.PageRequest;
import com.finesys.backend.common.model.base.PageResult;
import com.finesys.backend.common.model.user.UserModel;
import com.finesys.backend.common.utils.Const;
import com.finesys.backend.common.utils.HttpStatusCodes;
import com.finesys.backend.common.utils.JsonResult;
import com.finesys.backend.service.user.UserService;
import io.swagger.annotations.*;
import org.apache.dubbo.config.annotation.DubboReference;
import org.springframework.http.MediaType;
import org.springframework.validation.BindingResult;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpServletRequest;
import javax.validation.Valid;

/**
 * <p>Title: 用户相关api</p>
 * <p>Description: </p>
 * <p>Copyright: CopyRight (c) 2020-2035</p>
 * <p>Company: finesys Co. LTD.</p>
 * <p>Author: lehoon</p>
 * <p>Date: 2020.10.18</p>
 */
@Api("用户相关接口")
@RestController
@RequestMapping(RestApiConfig.USER_BASE_URL)
public class UserController extends BaseController {
	@DubboReference(version = "1.0.0", timeout = 600000, check = false, mock = "com.finesys.backend.service.user.UserServiceMock")
	private UserService userService;

	@LoggerPolicy(description = "用户登陆")
	@ApiOperation(value="用户登录", response = JsonResult.class, consumes = MediaType.APPLICATION_JSON_VALUE, produces = MediaType.APPLICATION_JSON_VALUE)
	@ApiResponses({
			@ApiResponse(code = 200, message = "登陆成功"),
			@ApiResponse(code = 401, message = "用户名密码错误"),
			@ApiResponse(code = 500, message = "登陆系统异常")
	})
	@PostMapping(value = RestApiConfig.USER_LOGIN_URL, consumes = MediaType.APPLICATION_JSON_VALUE, produces = MediaType.APPLICATION_JSON_VALUE)
	public String login(@RequestBody UserModel userModel) {
		if(userService == null) {
			return renderJson(HttpStatusCodes.SERVERERROR, "登陆系统异常");
		}

		String wsUrl = "";
		BusinessResult<String> result = userService.login(userModel.getUsername(), userModel.getPassword(), getRemoteAddress());
		if (result.isSuccess()) {
			return renderSuccessJson(result.getMessage(), new LoginInfoVo(result.getData(), wsUrl));
		}

		return renderErrorJson(result.getCode(), result.getMessage());
	}

	@LoggerPolicy(description = "用户注销")
	@ApiOperation(value="用户注销", response = JsonResult.class, consumes = MediaType.APPLICATION_JSON_VALUE)
	@ApiImplicitParams({
			@ApiImplicitParam(name= Const.ACCESS_TOKEN_KEY, value="token",required=true,dataType="String",paramType="query")
	})
	@RequestMapping(value = RestApiConfig.USER_LOGOUT_URL, method = {RequestMethod.GET, RequestMethod.POST})
	public String logout() {
		if(userService == null) {
			return renderJson(HttpStatusCodes.SERVERERROR, "用户系统异常");
		}

		String token = getAccessToken();
		BusinessResult<UserModel> logoutResult = userService.logout(token);

		if (!logoutResult.isSuccess()) {
			return renderErrorJson(logoutResult.getCode(), logoutResult.getMessage());
		}

		return renderSuccessJson("注销成功", logoutResult.getData().getUsername());
	}
	
	@LoggerPolicy(description="获取用户信息")
	@ApiOperation(value="获取用户信息", response = JsonResult.class, produces = MediaType.APPLICATION_JSON_VALUE)
	@ApiImplicitParam(name=Const.ACCESS_TOKEN_KEY,value="token",required=true,dataType="String",paramType="query")
	@GetMapping(value = RestApiConfig.USER_INFO_URL, produces = MediaType.APPLICATION_JSON_VALUE)
	public String profile(HttpServletRequest request) {
		UserModel userModel = (UserModel) request.getAttribute(Const.CURRENT_USER);
		return renderSuccessJson("操作成功", UserInfoVo.fromUserModel(userModel));
	}

	@LoggerPolicy(description = "用户新增")
	@ApiOperation(value="用户新增", response = JsonResult.class, consumes = MediaType.APPLICATION_JSON_VALUE, produces = MediaType.APPLICATION_JSON_VALUE)
	@ApiImplicitParams({
		@ApiImplicitParam(name=Const.ACCESS_TOKEN_KEY,value="token",required=true,dataType="String",paramType="query"),
		@ApiImplicitParam(name="username",value="登录名",required=true,dataType="String",paramType="query"),
		@ApiImplicitParam(name="password",value="密码",required=true,dataType="String",paramType="query"),
		@ApiImplicitParam(name="name",value="昵称",required=true,dataType="String",paramType="query"),
		@ApiImplicitParam(name="orgIds",value="组织机构",required=false,dataType="String",paramType="query"),
		@ApiImplicitParam(name="phone",value="手机号",required=false,dataType="String",paramType="query")
	})
	@PostMapping(value = RestApiConfig.USER_CREATE_URL, consumes = MediaType.APPLICATION_JSON_VALUE, produces = MediaType.APPLICATION_JSON_VALUE)
	public String create(@RequestBody @Valid UserModel userModel, BindingResult bindingResult) {
		if(bindingResult.hasErrors()) {
			StringBuilder sb = new StringBuilder(256);
			bindingResult.getFieldErrors().forEach(fieldError -> {
				sb.append(fieldError.getDefaultMessage());
				sb.append(",");
			});

			sb.deleteCharAt(sb.length() - 1);
			return renderErrorJson(600, sb.toString());
		}

		userModel.setRolename("business");
		BusinessResult<UserModel> result = userService.save(userModel);

		if(!result.isSuccess()) {
			return renderErrorJson(result.getCode(), result.getMessage());
		}

		return renderSuccessJson(result.getMessage(), result.getData());
	}

	@LoggerPolicy(description = "用户修改")
	@ApiOperation(value="用户修改", response = JsonResult.class, consumes = MediaType.APPLICATION_JSON_VALUE, produces = MediaType.APPLICATION_JSON_VALUE)
	@ApiImplicitParams({
			@ApiImplicitParam(name=Const.ACCESS_TOKEN_KEY,value="token",required=true,dataType="String",paramType="query"),
			@ApiImplicitParam(name="id", value="id", required=true, dataType="String",paramType="query"),
			@ApiImplicitParam(name="username",value="登录名",required=true,dataType="String",paramType="query"),
			@ApiImplicitParam(name="name",value="昵称",required=true,dataType="String",paramType="query"),
			@ApiImplicitParam(name="orgIds",value="组织机构",required=false,dataType="String",paramType="query"),
			@ApiImplicitParam(name="phone",value="手机号",required=false,dataType="String",paramType="query")
	})
	@PostMapping(value = RestApiConfig.USER_UPDATE_URL, consumes = MediaType.APPLICATION_JSON_VALUE, produces = MediaType.APPLICATION_JSON_VALUE)
	public String update(@RequestBody @Valid UserModel userModel, BindingResult bindingResult) {
		if(bindingResult.hasErrors()) {
			StringBuilder sb = new StringBuilder(256);
			bindingResult.getFieldErrors().forEach(fieldError -> {
				sb.append(fieldError.getDefaultMessage());
				sb.append(",");
			});

			sb.deleteCharAt(sb.length() - 1);
			return renderErrorJson(600, sb.toString());
		}

		BusinessResult<String> result = userService.update(userModel);

		if(result.isSuccess()) {
			return renderSuccessJson(result.getMessage());
		}

		return renderErrorJson(result.getCode(), result.getMessage());
	}

	@LoggerPolicy(description = "用户状态修改")
	@ApiOperation(value="用户状态修改", response = JsonResult.class, consumes = MediaType.APPLICATION_JSON_VALUE, produces = MediaType.APPLICATION_JSON_VALUE)
	@ApiImplicitParams({
			@ApiImplicitParam(name=Const.ACCESS_TOKEN_KEY,value="token",required=true,dataType="String",paramType="query"),
			@ApiImplicitParam(name="id", value="id", required=true, dataType="String",paramType="query"),
			@ApiImplicitParam(name="status",value="状态",required=true,dataType="String",paramType="query")
	})
	@PostMapping(value = RestApiConfig.USER_UPDATE_STATUS_URL, consumes = MediaType.APPLICATION_JSON_VALUE, produces = MediaType.APPLICATION_JSON_VALUE)
	public String update(@RequestBody UserModel userModel) {
		BusinessResult<String> result = userService.update(userModel);
		if(result.isSuccess()) {
			return renderSuccessJson(result.getMessage());
		}

		return renderErrorJson(result.getCode(), result.getMessage());
	}

	@LoggerPolicy(description = "用户密码修改")
	@ApiOperation(value="用户密码修改", response = JsonResult.class, consumes = MediaType.APPLICATION_JSON_VALUE, produces = MediaType.APPLICATION_JSON_VALUE)
	@ApiImplicitParams({
			@ApiImplicitParam(name=Const.ACCESS_TOKEN_KEY,value="token",required=true,dataType="String",paramType="query"),
			@ApiImplicitParam(name="id", value="id", required=true, dataType="String",paramType="query"),
			@ApiImplicitParam(name="password",value="密码",required=true,dataType="String",paramType="query")
	})
	@PostMapping(value = RestApiConfig.USER_UPDATE_PASSWORD_URL, consumes = MediaType.APPLICATION_JSON_VALUE, produces = MediaType.APPLICATION_JSON_VALUE)
	public String updatePassword(@RequestBody UserModel userModel) {
		BusinessResult<String> result = userService.update(userModel);
		if(result.isSuccess()) {
			return renderSuccessJson(result.getMessage());
		}

		return renderErrorJson(result.getCode(), result.getMessage());
	}

    @LoggerPolicy(description = "删除用户")
    @ApiOperation(value="删除用户", response = JsonResult.class, consumes = MediaType.APPLICATION_JSON_VALUE, produces = MediaType.APPLICATION_JSON_VALUE)
    @ApiImplicitParams({
            @ApiImplicitParam(name= Const.ACCESS_TOKEN_KEY, value="token", required=true, dataType="String",paramType="query"),
            @ApiImplicitParam(name="id", value="id", required=true, dataType="String",paramType="query")
    })
    @DeleteMapping(value = RestApiConfig.USER_DELETE_URL, consumes = MediaType.APPLICATION_JSON_VALUE, produces = MediaType.APPLICATION_JSON_VALUE)
    public String delete(@RequestBody UserModel userModel) {
        BusinessResult<String> result = userService.delete(userModel.getId());
		if(result.isSuccess()) {
			return renderSuccessJson(result.getMessage());
		}

		return renderErrorJson(result.getCode(), result.getMessage());
    }

	@LoggerPolicy(description = "分页查询用户")
	@ApiOperation(value="分页查询用户", response = JsonResult.class, produces = MediaType.APPLICATION_JSON_VALUE)
	@ApiImplicitParams({
			@ApiImplicitParam(name=Const.ACCESS_TOKEN_KEY, value="token", required=true, dataType="String",paramType="query"),
			@ApiImplicitParam(name="page", value="当前页码", required=true, dataType="int",paramType="query"),
			@ApiImplicitParam(name="limit", value="每页显示数", required=true, dataType="int",paramType="query")
	})
	@GetMapping(value = RestApiConfig.USER_PAGE_LIST_URL, produces = MediaType.APPLICATION_JSON_VALUE)
	public String findUserPage(@RequestParam int page, @RequestParam int limit) {
		BusinessResult<PageResult> result = userService.findPage(new PageRequest(page, limit, null));
		if (result.isSuccess()) {
			return renderSuccessJson("查询用户成功", result.getData());
		}

		return renderErrorJson(result.getCode(), result.getMessage());
	}
}
